home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / ObjectTcl-1.1 / CdlItem.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-30  |  12.0 KB  |  467 lines

  1. /*  _ __ ___ _
  2.  * | |\ /  /| |  $Id: CdlItem.C,v 1.9 1995/06/16 13:03:47 deans Exp $
  3.  * | | /  / | |  Copyright (C) 1995 IXI Limited.
  4.  * |_|/__/_\|_|  IXI Limited, Cambridge, England.
  5.  *
  6.  * Component   : CdlItem.C
  7.  *
  8.  * Author      : Dean Sheehan (deans@x.co.uk)
  9.  *
  10.  * Description : Contains the implementation for CdlClass and CdlPass, the two
  11.  *               top level entities within a CDL file.
  12.  *
  13.  * License     :
  14.             Object Tcl License & Copyright
  15.             ------------------------------
  16.  
  17. IXI Object Tcl software, both binary and source (hereafter, Software) is copyrighted by IXI Limited (IXI), and ownership remains with IXI. 
  18.  
  19. IXI grants you (herafter, Licensee) a license to use the Software for academic, research and internal business purposes only, without a fee. Licensee may distribute the binary and source code (if required) to third parties provided that the copyright notice and this statement appears on all copies and that no charge is associated with such copies. 
  20.  
  21. Licensee may make derivative works. However, if Licensee distributes any derivative work based on or derived from the Software, then Licensee will (1) notify IXI regarding its distribution of the derivative work, and (2) clearly notify users that such derivative work is a modified version and not the original IXI Object Tcl distributed by IXI. IXI strongly recommends that Licensee provide IXI the right to incorporate such modifications into future releases of the Software under these license terms. 
  22.  
  23. Any Licensee wishing to make commercial use of the Software should contact IXI, to negotiate an appropriate license for such commercial use. Commercial use includes (1) integration of all or part of the source code into a product for sale or license by or on behalf of Licensee to third parties, or (2) distribution of the binary code or source code to third parties that need it to utilize a commercial product sold or licensed by or on behalf of Licensee. 
  24.  
  25. IXI MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. IXI SHALL NOT BE LIABLE FOR ANY DAMAGES WHATSOEVER SUFFERED BY THE USERS OF THIS SOFTWARE. 
  26.  
  27. Copyright (C) 1995, IXI Limited 
  28.  
  29. By using or copying this Software, Licensee agrees to abide by the copyright law and all other applicable laws of England and the U.S., including, but not limited to, export control laws, and the terms of this license. IXI shall have the right to terminate this license immediately by written notice upon Licensee's breach of, or non-compliance with, any of its terms. Licensee may be held legally responsible for any copyright infringement that is caused or encouraged by Licensee's failure to abide by the terms of this license. 
  30.  
  31. Comments and questions are welcome and can be sent to
  32. otcl@x.co.uk 
  33.  
  34. For more information on copyright and licensing issues, contact: 
  35. Legal Department, IXI Limited, Vision Park, Cambridge CB4 4ZR,
  36. ENGLAND. 
  37.  
  38.  *
  39.  */
  40.  
  41. // System Includes
  42. #include <string.h>
  43. #include <stdlib.h>
  44.  
  45. // Tcl Includes
  46.  
  47. // Local Includes
  48. #include "CdlItem.H"
  49. #include "CdlMethod.H"
  50. #include "CdlFile.H"
  51.  
  52. CdlIndent::CdlIndent (int n)
  53. {
  54.    spaces = TAB * n;
  55. }
  56.  
  57. CdlIndent &CdlIndent::operator ++ (int)
  58. {
  59.    spaces += TAB;
  60.    return *this;
  61. }
  62.  
  63. CdlIndent &CdlIndent::operator ++ ()
  64. {
  65.    spaces += TAB;
  66.    return *this;
  67. }
  68.  
  69. CdlIndent &CdlIndent::operator -- (int)
  70. {
  71.    spaces -= TAB;
  72.    return *this;
  73. }
  74.  
  75. CdlIndent &CdlIndent::operator -- ()
  76. {
  77.    spaces -= TAB;
  78.    return *this;
  79. }
  80.  
  81. ofstream &operator << (ofstream &o, CdlIndent &c)
  82. {
  83.    for (int i = 0; i < c.spaces; i++)
  84.    {
  85.       o << " ";
  86.    }
  87.    return o;
  88. }
  89.  
  90. CdlItem::CdlItem ()
  91. {
  92. }
  93.  
  94. CdlItem::~CdlItem ()
  95. {
  96. }
  97.  
  98. CdlPass::CdlPass (char *l)
  99. {
  100.    pos = HEADER_AND_SOURCE;
  101.  
  102.    if (*l == '\n')
  103.    {
  104.       l++;
  105.    }
  106.    line = strdup(l);
  107.    if (line[strlen(line) - 1] == '\n')
  108.    {
  109.       line[strlen(line) - 1] = NULL;
  110.    }
  111. }
  112.  
  113. CdlPass::CdlPass (char *p, char *l)
  114. {
  115.    pos = HEADER_AND_SOURCE;
  116.  
  117.    if (strcmp(p,"-h") == 0)
  118.    {
  119.       pos = HEADER;
  120.    }
  121.    else if (strcmp(p,"-s") == 0)
  122.    {
  123.       pos = SOURCE;
  124.    }
  125.  
  126.    if (*l == '\n')
  127.    {
  128.       l++;
  129.    }
  130.    line = strdup(l);
  131.    if (line[strlen(line) - 1] == '\n')
  132.    {
  133.       line[strlen(line) - 1] = NULL;
  134.    }
  135. }
  136.  
  137. CdlPass::~CdlPass ()
  138. {
  139.    free(line);
  140. }
  141.  
  142. int CdlPass::genHeader (ofstream &o)
  143. {
  144.    if (pos == HEADER || pos == HEADER_AND_SOURCE)
  145.    {
  146.       o << line << endl;
  147.    }
  148.    return 0;
  149. }
  150.  
  151. int CdlPass::genSource (ofstream &o)
  152. {
  153.    if (pos == SOURCE || pos == HEADER_AND_SOURCE)
  154.    {
  155.       o << line << endl;
  156.    }
  157.    return 0;
  158. }
  159.  
  160. CdlClass::CdlClass (char *n, int noOfS, char *s[])
  161. {
  162.    name = strdup(n);
  163.    noOfInstanceMethods = 0;
  164.    noOfClassMethods = 0;
  165.    constructor = NULL;
  166.    noOfSuperclasses = noOfS;
  167.    superclasses = s;
  168. }
  169.  
  170. CdlClass::~CdlClass ()
  171. {
  172.    free(name);
  173.    if (constructor != NULL)
  174.    {
  175.       delete constructor;
  176.    }
  177.    for (int m = 0; m < noOfInstanceMethods; m++)
  178.    {
  179.       delete instanceMethod[m];
  180.    }
  181.    for (m = 0; m < noOfClassMethods; m++)
  182.    {
  183.       delete classMethod[m];
  184.    }
  185.    if (noOfSuperclasses != 0)
  186.    {
  187.       free(superclasses);
  188.    }
  189. }
  190.  
  191. char *CdlClass::giveName (void)
  192. {
  193.    return name;
  194. }
  195.  
  196. void CdlClass::addInstanceMethod (CdlInstanceMethod *m)
  197. {
  198.    instanceMethod[noOfInstanceMethods] = m;
  199.    noOfInstanceMethods++;
  200. }
  201.  
  202. void CdlClass::addClassMethod (CdlClassMethod *m)
  203. {
  204.    classMethod[noOfClassMethods] = m;
  205.    noOfClassMethods++;
  206. }
  207.  
  208. void CdlClass::setConstructor (CdlConstructor *c)
  209. {
  210.    constructor = c;
  211. }
  212.  
  213. CdlConstructor *CdlClass::getConstructor (void)
  214. {
  215.    return constructor;
  216. }
  217.  
  218. int CdlClass::genHeader (ofstream &o)
  219. {
  220.    genOtclClassDec(o);
  221.    o << endl;
  222.    genOtclPartDec(o);
  223.    o << endl;
  224.  
  225.    return 1;
  226. }
  227.  
  228. int CdlClass::genSource (ofstream &o)
  229. {
  230.    genOtclClassDef(o);
  231.    o << endl;
  232.    genOtclPartDef(o);
  233.    o << endl;
  234.    return 1;
  235. };
  236.  
  237. void CdlClass::genOtclClassDec (ofstream &o)
  238. {
  239.    CdlIndent tab(1);
  240.  
  241.    o << "class " << name << OTCL_CLASS_SUFFIX << " : public OtclClassCpp"<<endl;
  242.    o << "{" << endl;
  243.    o << "public:" << endl;
  244.    o << tab << name << OTCL_CLASS_SUFFIX << " ();" << endl;
  245.    o << tab << "OtclPart *instantiatePart (Tcl_Interp *, int *, int," << endl;
  246.    o << tab << "                           char *[], OtclObject *," << endl;
  247.    o << tab << "                           OtclPart **partPtr);" << endl;
  248.    o << tab << "static " << name << OTCL_CLASS_SUFFIX << " instance;" << endl;
  249.    o << tab << "int classMethod (Tcl_Interp *, int, char *[]); " << endl;
  250.    o << "};" << endl;
  251. }
  252.  
  253. void CdlClass::genOtclClassDef (ofstream &of)
  254. {
  255.    CdlIndent tab(1);
  256.  
  257.    // Static Attribute Definition
  258.    of << name << OTCL_CLASS_SUFFIX << " " << name << OTCL_CLASS_SUFFIX
  259.       << "::instance;" << endl;
  260.  
  261.    of << endl;
  262.  
  263.    // Constructor Definition
  264.    of << name << OTCL_CLASS_SUFFIX << "::" << name << OTCL_CLASS_SUFFIX
  265.       << " () : ";
  266.    of << "OtclClassCpp(\"" << name << "\") {}" << endl;
  267.  
  268.    of << endl;
  269.  
  270.    // ::instatntiatePart(...)
  271.    of << "OtclPart *" << name << OTCL_CLASS_SUFFIX << "::instantiatePart (" 
  272.       << "Tcl_Interp *i," << endl;
  273.    of << tab << "int *returnCode, int argc," << endl;
  274.    of << tab << "char *argv[], OtclObject *o," << endl;
  275.    of << tab << "OtclPart **partPtr)" << endl;
  276.    of << "{" << endl;
  277.  
  278.    of << tab << "if (argc != " << constructor->getNoOfArgs() << ")" << endl;
  279.    of << tab << "{" << endl;
  280.    tab++;
  281.    of << tab << "*returnCode = TCL_ERROR;" << endl;
  282.    of << tab << "Otcl::setTclResult(i,ARGS_METHOD_ERR,\"constructor\","
  283.       << "\"" << name << "\");" << endl;
  284.    of << tab << "return NULL;" << endl;
  285.    tab--;
  286.    of << tab << "}" << endl;
  287.  
  288. // Exception if argc no enough
  289.  
  290.    constructor->preProcessArgs(of,tab);
  291.  
  292.    of << tab << "OtclPart *res = new " << name << OTCL_PART_SUFFIX << " (";
  293.  
  294.    constructor->passArgs(of,"o");
  295.  
  296.    of << ");" << endl;
  297.  
  298.    constructor->postProcessArgs(of,tab);
  299.  
  300.    of << tab << "*partPtr = res;" << endl;
  301.    
  302.    of << tab << "return res;" << endl; 
  303.  
  304.    of << "}" << endl;
  305.  
  306.    of << endl;
  307.  
  308.    // classMethod
  309.  
  310.    of << "int " << name << OTCL_CLASS_SUFFIX << "::classMethod ("
  311.       << "Tcl_Interp *i, int argc, char *argv[])" << endl;
  312.    of << "{" << endl;
  313.    for (int m = 0; m < noOfClassMethods; m++)
  314.    {
  315.       classMethod[m]->executeBinding(name,of,tab);
  316.       of << endl;
  317.    }
  318.    of << tab << "Otcl::setTclResult(i,CLASS_METHOD_NOT_FOUND_ERR,"
  319.       << "argv[1],\"" << name << "\");" << endl;
  320.    of << tab << "return TCL_ERROR;" << endl;
  321.    of << "}" << endl;
  322. }
  323.  
  324. void CdlClass::genOtclPartDec (ofstream &of)
  325. {
  326.    of << "class " << name << OTCL_PART_SUFFIX << " : public OtclPartCpp, "
  327.       << "public " << name << endl;
  328.    of << "{" << endl;
  329.    of << "public:" << endl;
  330.  
  331.    constructor->genDec(of);
  332.  
  333.    of << endl;
  334.  
  335.    // Copy constructor:
  336.    of << "   " << name << OTCL_PART_SUFFIX << "(const " << name << " &);"
  337.       << endl;
  338.  
  339.    of << "   ~" << name << OTCL_PART_SUFFIX << " ();" << endl;
  340.  
  341.    for (int m = 0; m < noOfInstanceMethods; m++)
  342.    {
  343.       if (instanceMethod[m]->isDynamic())
  344.       {
  345.          instanceMethod[m]->genDec(of);
  346.       }
  347.    }
  348.  
  349.    of << "   char *giveClassName (void);" << endl;
  350.    of << "   int executeMethod (Tcl_Interp *, char *, int, char *[], int*);" 
  351.       << endl;
  352.    of << "   int discardPart (Tcl_Interp *, int);" << endl;
  353.    of << "   void *toCpp (char *);" << endl;
  354.  
  355.    of << "};" << endl;
  356. }
  357.  
  358. void CdlClass::genOtclPartDef (ofstream &of)
  359. {
  360.    // Constructor from OTCL instantiation
  361.    of << name << OTCL_PART_SUFFIX << "::" << name << OTCL_PART_SUFFIX << " (";
  362.  
  363.    constructor->defineArgs(of);
  364.  
  365.    of << ") :" << endl;
  366.    of << "   " << name << "(";
  367.  
  368.    constructor->passArgsUpwards(of);
  369.  
  370.    of << ")," << endl;
  371.  
  372.    // Arg pass to parent classes
  373.    of << "   OtclPartCpp(o) {}" << endl;
  374.  
  375.    of << endl;
  376.  
  377.    // Copy constructor
  378.    of << name << OTCL_PART_SUFFIX << "::" << name << OTCL_PART_SUFFIX << " (";
  379.    of << "const " << name << " &obj) :" << endl;
  380.    of << "   " << name << "(obj)," << endl;
  381.    of << "    OtclPartCpp(NULL)" << endl;
  382.    of << "{" << endl;
  383.    of << "}" << endl;
  384.    
  385.  
  386.    // Destructor
  387.    of << name << OTCL_PART_SUFFIX << "::~" << name << OTCL_PART_SUFFIX 
  388.       << "()" << endl;
  389.    of << "{" << endl;
  390.    of << "   if (!owner->discardingParts())" << endl;
  391.    of << "   {" << endl;
  392.    of << "      Otcl::otclPtr->discard(Otcl::tclInterp,owner->getSelf(),"
  393.       << "OTCL_TRUE);" << endl;
  394.    of << "   }" << endl;
  395.    of << "}" << endl;
  396.  
  397.    of << endl;
  398.  
  399.    // giveClassName
  400.    of << "char *" << name << OTCL_PART_SUFFIX << "::giveClassName (void)" << endl;
  401.    of << "{" << endl;
  402.    of << "   return \"" << name << "\";" << endl;
  403.    of << "}" << endl;
  404.  
  405.    // discardPart
  406.    of << "int " << name << OTCL_PART_SUFFIX
  407.       << "::discardPart (Tcl_Interp *, int fromCpp)" << endl;
  408.    of << "{" << endl;
  409.    of << "   if (fromCpp == OTCL_TRUE) return TCL_OK;" << endl;
  410.    of << "   delete this;" << endl;
  411.    of << "   return TCL_OK;" << endl;
  412.    of << "}" << endl;
  413.  
  414.    of << endl;
  415.  
  416.    // toCpp
  417.    of << "void *" << name << OTCL_PART_SUFFIX
  418.       << "::toCpp (char *cppClassName)" << endl;
  419.    of << "{" << endl;
  420.  
  421.    of << "   if (strcmp(cppClassName,\"" << name << "\") == 0)" << endl;
  422.    of << "   {" << endl;
  423.    of << "      return (void*)((" << name << "*)this);" << endl;
  424.    of << "   }" << endl;
  425.  
  426.    for (int s = 0; s < noOfSuperclasses; s++)
  427.    {
  428.       of << "   if (strcmp(cppClassName,\"" << superclasses[s] << "\") == 0)"
  429.          << endl;
  430.       of << "   {" << endl;
  431.       of << "      return (void*)((" << superclasses[s] << "*)this);" << endl;
  432.       of << "   }" << endl;
  433.    } 
  434.  
  435.    of << "   return NULL;" << endl;
  436.    of << "}" << endl;
  437.  
  438.    of << endl;
  439.  
  440.    // executeMethod
  441.    of << "int " << name << OTCL_PART_SUFFIX << "::executeMethod (Tcl_Interp *i,"
  442.       << " char *mName, int argc," << endl;
  443.    of << "         char *argv[], int *found)" << endl;
  444.    of << "{" << endl;
  445.  
  446.    for (int m = 0; m < noOfInstanceMethods; m++)
  447.    {
  448.       instanceMethod[m]->executeBinding(name,of);
  449.       of << endl;
  450.    }
  451.  
  452.    of << "   *found = OTCL_FALSE;" << endl;
  453.    of << "   return TCL_OK;" << endl;
  454.    of << "}" << endl;
  455.  
  456.    // Dynamic method definitions
  457.    for (m = 0; m < noOfInstanceMethods; m++)
  458.    {
  459.       if (instanceMethod[m]->isDynamic())
  460.       {
  461.          of << endl;
  462.          instanceMethod[m]->genDef(name,of);
  463.       }
  464.    }
  465. }
  466.  
  467.